package main

import (
	"bytes"
	"fmt"
	"github.com/spf13/viper"
	"log"
	"os"
	"strings"
)

// viper 支持以下功能：
//  1. 支持Yaml、Json、 TOML、HCL 等格式的配置
//  2. 可以从文件、io、环境变量、command line中提取配置
//  3. 支持自动转换的类型解析
//  4. 可以远程从etcd中读取配置

const cmdRoot = "core"

func main() {
	ReadConfigFromIO()
}

// 从IO读取
func ReadConfigFromIO()  {
	if f,err := os.Open("core.yaml");err != nil{
		log.Panicf("failure: %s",err.Error())
	}else{
		confLen, _ := f.Seek(0,2)
		//注意，通常写c++的习惯害怕读取字符串的时候越界，都会多留出一个NULL在末尾，但是在这里不行，会报出如下错误：
		//While parsing config: yaml: control characters are not allowed
		//错误参考网址：https://stackoverflow.com/questions/33717799/go-yaml-control-characters-are-not-allowed-error
		configData := make([]byte,confLen)
		f.Seek(0,0)
		f.Read(configData)
		log.Printf("%s\n", string(configData))

		viper.SetConfigType("yaml")
		if err := viper.ReadConfig(bytes.NewBuffer(configData));err != nil {
			log.Fatal(err.Error())
		}
	}
	log.Printf("recoverdamage: %v, abcd: %v \n", viper.Get("statetransfer.recoverdamage"), viper.Get("peer.abcd"));
}
// CORE_SECURITY_ENABLED=true go run test1.go
// 从环境变量读取
func EnvConfigPrefix()  {
	// 设置环境变量前缀
	viper.SetEnvPrefix(cmdRoot)
	// 会获取所有的环境变量，同时如果过设置了前缀则会自动补全前缀名
	viper.AutomaticEnv()
	// 方便的替换符
	replacer := strings.NewReplacer(".", "_")
	viper.SetEnvKeyReplacer(replacer)

	environment := viper.GetBool("security.enabled")
	fmt.Println("security.enabled:", environment)
}
// 从 yaml 文件读取
func LoadConfigFromYaml()  {
	// 设置配置文件的名字
	viper.SetConfigName(cmdRoot)
	// 注意：如果不用AddConfigPath去指定路径，它会在程序执行的目录去寻找
	//添加配置文件所在的路径,注意在Linux环境下%GOPATH要替换为$GOPATH
	//viper.AddConfigPath("%GOPATH/src/")
	viper.AddConfigPath("./")
	// 设置配置文件类型
	viper.SetConfigType("yaml")

	err := viper.ReadInConfig()
	if err != nil {
		fmt.Println(fmt.Errorf("Fatal error when reading %s config file:%s", cmdRoot, err))
		os.Exit(1)
	}
	fullstate := viper.GetString("statetransfer.timeout.fullstate")
	fmt.Println("statetransfer.timeout.fullstate:", fullstate)

	abcdValue := viper.GetString("peer.abcd")
	fmt.Println("peer.abcd:", abcdValue)
}